{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f8357a63-2129-436f-97ab-f5541f91ee40",
   "metadata": {},
   "source": [
    "# Install Packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "c5d69867-ab4a-46ae-8346-87a6efb26b63",
   "metadata": {},
   "outputs": [],
   "source": [
    "#!pip3 install langchain"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43c4c752-6438-414f-93b4-0d4d12ce4528",
   "metadata": {},
   "source": [
    "# Import packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "d0c64bbc-4ba6-4513-930f-a0f5e03a6e97",
   "metadata": {},
   "outputs": [],
   "source": [
    "from dotenv import load_dotenv\n",
    "from langchain.embeddings import OpenAIEmbeddings\n",
    "from langchain.vectorstores import ElasticsearchStore\n",
    "from langchain.text_splitter import CharacterTextSplitter\n",
    "from langchain.prompts import ChatPromptTemplate\n",
    "from langchain.prompts import PromptTemplate\n",
    "from langchain.chat_models import ChatOpenAI\n",
    "from langchain.schema.output_parser import StrOutputParser\n",
    "from langchain.schema.runnable import RunnablePassthrough\n",
    "from langchain.schema.runnable import RunnableLambda\n",
    "from langchain.schema import HumanMessage\n",
    "from urllib.request import urlopen\n",
    "import os, json\n",
    " \n",
    "load_dotenv()\n",
    " \n",
    "openai_api_key=os.getenv('OPENAI_API_KEY')\n",
    "elastic_user=os.getenv('ES_USER')\n",
    "elastic_password=os.getenv('ES_PASSWORD')\n",
    "elastic_endpoint=os.getenv(\"ES_ENDPOINT\")\n",
    "elastic_index_name='langchain-rag'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61ef283e-0d98-404c-8254-bd3d96e1a66b",
   "metadata": {},
   "source": [
    "# Add documents and split them into passages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "dafd82af-e4f4-407d-aaf0-760c42612973",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Successfully loaded 15 documents\n"
     ]
    }
   ],
   "source": [
    "with open('workplace-docs.json') as f:\n",
    "   workplace_docs = json.load(f)\n",
    " \n",
    "print(f\"Successfully loaded {len(workplace_docs)} documents\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "d61db5c9-2cde-434c-a8fd-4a2e130e92c8",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Created a chunk of size 245, which is longer than the specified 50\n",
      "Created a chunk of size 288, which is longer than the specified 50\n",
      "Created a chunk of size 204, which is longer than the specified 50\n",
      "Created a chunk of size 281, which is longer than the specified 50\n",
      "Created a chunk of size 249, which is longer than the specified 50\n",
      "Created a chunk of size 285, which is longer than the specified 50\n",
      "Created a chunk of size 298, which is longer than the specified 50\n",
      "Created a chunk of size 270, which is longer than the specified 50\n",
      "Created a chunk of size 224, which is longer than the specified 50\n",
      "Created a chunk of size 288, which is longer than the specified 50\n",
      "Created a chunk of size 260, which is longer than the specified 50\n",
      "Created a chunk of size 199, which is longer than the specified 50\n",
      "Created a chunk of size 290, which is longer than the specified 50\n",
      "Created a chunk of size 251, which is longer than the specified 50\n",
      "Created a chunk of size 195, which is longer than the specified 50\n",
      "Created a chunk of size 242, which is longer than the specified 50\n",
      "Created a chunk of size 275, which is longer than the specified 50\n",
      "Created a chunk of size 277, which is longer than the specified 50\n",
      "Created a chunk of size 284, which is longer than the specified 50\n",
      "Created a chunk of size 285, which is longer than the specified 50\n",
      "Created a chunk of size 324, which is longer than the specified 50\n",
      "Created a chunk of size 328, which is longer than the specified 50\n",
      "Created a chunk of size 280, which is longer than the specified 50\n",
      "Created a chunk of size 123, which is longer than the specified 50\n",
      "Created a chunk of size 221, which is longer than the specified 50\n",
      "Created a chunk of size 330, which is longer than the specified 50\n",
      "Created a chunk of size 292, which is longer than the specified 50\n",
      "Created a chunk of size 240, which is longer than the specified 50\n",
      "Created a chunk of size 232, which is longer than the specified 50\n",
      "Created a chunk of size 324, which is longer than the specified 50\n",
      "Created a chunk of size 167, which is longer than the specified 50\n",
      "Created a chunk of size 181, which is longer than the specified 50\n",
      "Created a chunk of size 353, which is longer than the specified 50\n",
      "Created a chunk of size 471, which is longer than the specified 50\n",
      "Created a chunk of size 400, which is longer than the specified 50\n",
      "Created a chunk of size 607, which is longer than the specified 50\n",
      "Created a chunk of size 440, which is longer than the specified 50\n",
      "Created a chunk of size 788, which is longer than the specified 50\n",
      "Created a chunk of size 547, which is longer than the specified 50\n",
      "Created a chunk of size 67, which is longer than the specified 50\n",
      "Created a chunk of size 635, which is longer than the specified 50\n",
      "Created a chunk of size 440, which is longer than the specified 50\n",
      "Created a chunk of size 464, which is longer than the specified 50\n",
      "Created a chunk of size 372, which is longer than the specified 50\n",
      "Created a chunk of size 866, which is longer than the specified 50\n",
      "Created a chunk of size 111, which is longer than the specified 50\n",
      "Created a chunk of size 361, which is longer than the specified 50\n",
      "Created a chunk of size 110, which is longer than the specified 50\n",
      "Created a chunk of size 471, which is longer than the specified 50\n",
      "Created a chunk of size 288, which is longer than the specified 50\n",
      "Created a chunk of size 150, which is longer than the specified 50\n",
      "Created a chunk of size 62, which is longer than the specified 50\n",
      "Created a chunk of size 619, which is longer than the specified 50\n",
      "Created a chunk of size 257, which is longer than the specified 50\n",
      "Created a chunk of size 310, which is longer than the specified 50\n",
      "Created a chunk of size 310, which is longer than the specified 50\n",
      "Created a chunk of size 282, which is longer than the specified 50\n",
      "Created a chunk of size 230, which is longer than the specified 50\n",
      "Created a chunk of size 213, which is longer than the specified 50\n",
      "Created a chunk of size 395, which is longer than the specified 50\n",
      "Created a chunk of size 270, which is longer than the specified 50\n",
      "Created a chunk of size 224, which is longer than the specified 50\n",
      "Created a chunk of size 292, which is longer than the specified 50\n",
      "Created a chunk of size 231, which is longer than the specified 50\n",
      "Created a chunk of size 153, which is longer than the specified 50\n",
      "Created a chunk of size 277, which is longer than the specified 50\n",
      "Created a chunk of size 171, which is longer than the specified 50\n",
      "Created a chunk of size 106, which is longer than the specified 50\n",
      "Created a chunk of size 253, which is longer than the specified 50\n",
      "Created a chunk of size 140, which is longer than the specified 50\n",
      "Created a chunk of size 323, which is longer than the specified 50\n",
      "Created a chunk of size 95, which is longer than the specified 50\n",
      "Created a chunk of size 201, which is longer than the specified 50\n",
      "Created a chunk of size 174, which is longer than the specified 50\n",
      "Created a chunk of size 232, which is longer than the specified 50\n",
      "Created a chunk of size 238, which is longer than the specified 50\n",
      "Created a chunk of size 193, which is longer than the specified 50\n",
      "Created a chunk of size 305, which is longer than the specified 50\n",
      "Created a chunk of size 1120, which is longer than the specified 50\n",
      "Created a chunk of size 397, which is longer than the specified 50\n",
      "Created a chunk of size 320, which is longer than the specified 50\n",
      "Created a chunk of size 567, which is longer than the specified 50\n",
      "Created a chunk of size 300, which is longer than the specified 50\n",
      "Created a chunk of size 217, which is longer than the specified 50\n",
      "Created a chunk of size 271, which is longer than the specified 50\n",
      "Created a chunk of size 264, which is longer than the specified 50\n",
      "Created a chunk of size 340, which is longer than the specified 50\n",
      "Created a chunk of size 383, which is longer than the specified 50\n",
      "Created a chunk of size 243, which is longer than the specified 50\n",
      "Created a chunk of size 344, which is longer than the specified 50\n",
      "Created a chunk of size 225, which is longer than the specified 50\n",
      "Created a chunk of size 208, which is longer than the specified 50\n",
      "Created a chunk of size 420, which is longer than the specified 50\n",
      "Created a chunk of size 89, which is longer than the specified 50\n",
      "Created a chunk of size 94, which is longer than the specified 50\n",
      "Created a chunk of size 299, which is longer than the specified 50\n",
      "Created a chunk of size 310, which is longer than the specified 50\n"
     ]
    }
   ],
   "source": [
    "metadata = []\n",
    "content = []\n",
    " \n",
    "for doc in workplace_docs:\n",
    "  content.append(doc[\"content\"])\n",
    "  metadata.append({\n",
    "      \"name\": doc[\"name\"],\n",
    "      \"summary\": doc[\"summary\"],\n",
    "      \"rolePermissions\":doc[\"rolePermissions\"]\n",
    "  })\n",
    " \n",
    "text_splitter = CharacterTextSplitter(chunk_size=50, chunk_overlap=0)\n",
    "docs = text_splitter.create_documents(content, metadatas=metadata)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f22e37d3-3f69-42ac-8ff7-8815d2482012",
   "metadata": {},
   "source": [
    "# Index Documents using ELSER - SparseVectorRetrievalStrategy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "73799250-1b2f-432e-8789-9c3facd18053",
   "metadata": {},
   "outputs": [],
   "source": [
    "from elasticsearch import Elasticsearch\n",
    "\n",
    "url = f\"https://{elastic_user}:{elastic_password}@{elastic_endpoint}:9200\"\n",
    "connection = Elasticsearch(url, ca_certs = \"./http_ca.crt\", verify_certs = True)\n",
    "\n",
    "es = ElasticsearchStore.from_documents(\n",
    "    docs,\n",
    "    es_url = url,\n",
    "    es_connection = connection,\n",
    "    es_user=elastic_user,\n",
    "    es_password=elastic_password,\n",
    "    index_name=elastic_index_name,\n",
    "    strategy=ElasticsearchStore.SparseVectorRetrievalStrategy()\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "04ad7dc1-f275-4502-b4be-cf376b5eac1c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<langchain.vectorstores.elasticsearch.ElasticsearchStore at 0x107ce5b50>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "es"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e02b6fb-cde1-48a9-8131-7d0813d643d3",
   "metadata": {},
   "source": [
    "# Show Result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "e804823e-473c-43b5-9220-55c49be09578",
   "metadata": {},
   "outputs": [],
   "source": [
    "def showResults(output):\n",
    "  print(\"Total results: \", len(output))\n",
    "  for index in range(len(output)):\n",
    "    print(output[index])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82c8993c-766f-4f1c-999e-382da7aba226",
   "metadata": {},
   "source": [
    "# Search"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "d49cfb12-395b-4a3b-944e-857c5ac63e90",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total results:  4\n",
      "page_content='The purpose of this full-time work-from-home policy is to provide guidelines and support for employees to conduct their work remotely, ensuring the continuity and productivity of business operations during the COVID-19 pandemic and beyond.\\nScope' metadata={'summary': 'This policy outlines the guidelines for full-time remote work, including eligibility, equipment and resources, workspace requirements, communication expectations, performance expectations, time tracking and overtime, confidentiality and data security, health and well-being, and policy reviews and updates. Employees are encouraged to direct any questions or concerns', 'rolePermissions': ['demo', 'manager'], 'name': 'Work From Home Policy'}\n",
      "page_content='This work-from-home policy will be reviewed periodically and updated as necessary, taking into account changes in public health guidance, business needs, and employee feedback.\\nQuestions and Concerns' metadata={'summary': 'This policy outlines the guidelines for full-time remote work, including eligibility, equipment and resources, workspace requirements, communication expectations, performance expectations, time tracking and overtime, confidentiality and data security, health and well-being, and policy reviews and updates. Employees are encouraged to direct any questions or concerns', 'rolePermissions': ['demo', 'manager'], 'name': 'Work From Home Policy'}\n",
      "page_content=\"Employees must adhere to the company's confidentiality and data security policies while working from home. This includes safeguarding sensitive information, securing personal devices and internet connections, and reporting any security breaches to the IT department.\\nHealth and Well-being\" metadata={'summary': 'This policy outlines the guidelines for full-time remote work, including eligibility, equipment and resources, workspace requirements, communication expectations, performance expectations, time tracking and overtime, confidentiality and data security, health and well-being, and policy reviews and updates. Employees are encouraged to direct any questions or concerns', 'rolePermissions': ['demo', 'manager'], 'name': 'Work From Home Policy'}\n",
      "page_content='This policy applies to all employees who are eligible for remote work as determined by their role and responsibilities. It is designed to allow employees to work from home full time while maintaining the same level of performance and collaboration as they would in the office.\\nEligibility' metadata={'summary': 'This policy outlines the guidelines for full-time remote work, including eligibility, equipment and resources, workspace requirements, communication expectations, performance expectations, time tracking and overtime, confidentiality and data security, health and well-being, and policy reviews and updates. Employees are encouraged to direct any questions or concerns', 'rolePermissions': ['demo', 'manager'], 'name': 'Work From Home Policy'}\n"
     ]
    }
   ],
   "source": [
    "r = es.similarity_search(\"work from home policy\")\n",
    "showResults(r)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3b329de6-a3b3-4366-a2a7-d11305bc9ee0",
   "metadata": {},
   "source": [
    "# RAG with Elasticsearch - Method 1 (Using Retriever)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "551d5c3c-a62f-433a-9c18-33146a645a03",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'The vacation policy outlines the guidelines and procedures for requesting and taking time off from work for personal and leisure purposes. Full-time employees accrue vacation time at a rate of [X hours] per month, equivalent to [Y days] per year. Vacation requests must be submitted to supervisors at least [A weeks] in advance. The policy applies to all full-time and part-time employees who have completed their probationary period.'"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "retriever = es.as_retriever(search_kwargs={\"k\": 4})\n",
    "\n",
    "template = \"\"\"Answer the question based only on the following context:\n",
    "{context}\n",
    "\n",
    "Question: {question}\n",
    "\"\"\"\n",
    "prompt = ChatPromptTemplate.from_template(template)\n",
    "\n",
    "chain = (\n",
    "    {\"context\": retriever, \"question\": RunnablePassthrough()} \n",
    "    | prompt \n",
    "    | ChatOpenAI() \n",
    "    | StrOutputParser()\n",
    ")\n",
    "\n",
    "chain.invoke(\"vacation policy\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5560501e-b098-49ba-a368-138c5f3b176a",
   "metadata": {},
   "source": [
    "# RAG with Elasticsearch - Method 2 (Without Retriever)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2723c158-8935-4398-9864-8bdbefd40ce4",
   "metadata": {},
   "source": [
    "## Add Context"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "9c846a16-7942-48ca-91aa-b4f8a1337e44",
   "metadata": {},
   "outputs": [],
   "source": [
    "def add_context(question: str):\n",
    "    r = es.similarity_search(question)\n",
    "    \n",
    "    context = \"\\n\".join(x.page_content for x in r)\n",
    "    \n",
    "    return context"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5f510dc7-1b4f-4a4c-b3ef-a3ad2d3ea371",
   "metadata": {},
   "source": [
    "## Chain"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "3943fa03-86ce-46f5-8e24-c761b185f526",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Employees in Canada must follow all health and safety guidelines and procedures to maintain a safe and healthy work environment. This includes reporting any hazards or unsafe conditions to the appropriate personnel. Additionally, starting May 2022, the company will be implementing a two-day in-office work requirement per week for all eligible employees. Employees are advised to coordinate with their supervisor and HR department to schedule their in-office workdays while continuing to follow all safety protocols.'"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "template = \"\"\"Answer the question based only on the following context:\n",
    "{context}\n",
    "\n",
    "Question: {question}\n",
    "\"\"\"\n",
    "\n",
    "prompt = ChatPromptTemplate.from_template(template)\n",
    "\n",
    "chain = (\n",
    "    {\"context\": RunnableLambda(add_context), \"question\": RunnablePassthrough()}\n",
    "    | prompt\n",
    "    | ChatOpenAI()\n",
    "    | StrOutputParser()\n",
    ")\n",
    "\n",
    "chain.invoke(\"canada employees guidelines\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "800a7e9f-29ba-4447-96e7-596fcc971f45",
   "metadata": {},
   "source": [
    "# Compare with RAG and without RAG"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "d646718e-833a-4e5b-9976-3359498142fa",
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "Ask Question:  detailed steps for new employee onboarding\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "ChatGPT Response:\n",
      "\n",
      "content=\"Onboarding a new employee is a crucial step in their integration into your organization. Here are some detailed steps for a comprehensive new employee onboarding process:\\n\\n1. Pre-boarding:\\n   a. Send a welcome email: Before the employee's first day, send them a welcome email that includes information about their start date, time, location, dress code, and any documents they need to bring.\\n   b. Prepare their workspace: Make sure the employee's workspace is clean, organized, and equipped with the necessary tools and technology they will need.\\n\\n2. First day orientation:\\n   a. Meet and greet: Have someone from the HR department or the employee's supervisor greet them on their first day, introduce themselves, and give them a tour of the office.\\n   b. Provide necessary paperwork: Present the employee with any paperwork they need to complete, such as tax forms, employment contracts, and company policies.\\n   c. Explain policies and procedures: Go over important company policies, such as attendance, leave, and code of conduct. Provide them with an employee handbook or any other relevant materials.\\n   d. Introduce the team: Arrange a meeting with the employee's team members and introduce them to each other. Encourage team members to share their roles and responsibilities.\\n   e. Assign a mentor or buddy: Pair the new employee with an experienced team member who can guide and support them during their initial days.\\n\\n3. Training and development:\\n   a. Job-specific training: Provide the employee with job-specific training relevant to their role. This can include shadowing, online courses, or in-person training sessions.\\n   b. Company-wide training: Schedule sessions to educate the new employee about the company's mission, values, products/services, and target market.\\n   c. IT and system training: Ensure the employee is trained on any software, tools, or systems they will be using in their job. This can include email, project management software, CRM systems, etc.\\n   d. Performance expectations: Set clear performance expectations, goals, and objectives for the employee and discuss how their performance will be evaluated.\\n\\n4. Integration and engagement:\\n   a. Team-building activities: Organize team-building activities or events to foster relationships and create a positive work environment.\\n   b. Socialize with colleagues: Encourage the employee to have lunch or coffee breaks with different team members to build connections and learn more about the company culture.\\n   c. Provide resources: Offer access to resources like employee handbooks, training materials, and online platforms where they can find information and engage with colleagues.\\n   d. Regular check-ins: Schedule regular check-ins with the new employee to address any questions or concerns they may have and ensure they are progressing well.\\n\\n5. Follow-up and evaluation:\\n   a. Feedback sessions: Conduct regular feedback sessions with the new employee to discuss their progress, address any issues, and provide guidance for improvement.\\n   b. Performance evaluations: Conduct performance evaluations at regular intervals to assess the employee's progress and provide constructive feedback.\\n   c. Continuous learning and growth: Encourage the employee to participate in professional development opportunities, such as workshops, conferences, or online courses.\\n\\nRemember, effective onboarding is an ongoing process that extends beyond the initial weeks. It should focus on helping the new employee acclimate to their role, team, and the organization as a whole.\"\n",
      "\n",
      "ChatGPT with RAG Response:\n",
      "\n",
      "1. Attend orientation: Attend the orientation session to meet colleagues and learn about the company's history, mission, and values.\n",
      "2. Review policies and procedures: Familiarize yourself with the employee handbook, which contains important information about company policies and procedures. Read it thoroughly and adhere to the guidelines.\n",
      "3. Complete required training: Attend and complete any mandatory training sessions, such as safety training or anti-harassment training, as soon as possible.\n",
      "4. Complete tax forms: Fill out the necessary tax forms for your country or region to determine the amount of income tax withheld from your paycheck. Update them if your personal or financial situation changes.\n",
      "5. Submit regional tax forms: Check with the HR department to determine if you need to complete additional regional or local tax forms based on your location.\n",
      "6. Update your address: Inform the HR department if you move to ensure accurate tax reporting.\n",
      "7. Review benefits options: Carefully review the benefits package and choose the options that best suit your needs.\n",
      "8. Complete enrollment forms: Fill out the necessary forms to enroll in your chosen benefits and submit them to the HR department within 30 days of your start date.\n",
      "9. Designate beneficiaries: If applicable, designate beneficiaries for your life insurance and retirement plans.\n",
      "10. Set up your workstation: Organize your desk, chair, and computer according to your preferences. Contact the HR department if you require any additional equipment or accommodations.\n",
      "11. Obtain necessary supplies: Request any required office supplies from the designated supply area or appropriate department.\n",
      "12. Familiarize yourself with office resources: Locate common areas and familiarize yourself with office equipment.\n",
      "13. Maintain regular work hours: Be available during normal business hours unless otherwise agreed upon with your supervisor. Any changes to work hours or availability must be communicated to your supervisor and the HR department.\n",
      "14. Obtain approval for bringing pets to the office: Obtain prior approval from your supervisor and the HR department before bringing pets to the office.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "q = input(\"Ask Question: \")\n",
    "\n",
    "## Question to OpenAI\n",
    "\n",
    "chat = ChatOpenAI()\n",
    "\n",
    "messages = [\n",
    "    HumanMessage(\n",
    "        content=q\n",
    "    )\n",
    "]\n",
    "\n",
    "gpt_res = chat(messages)\n",
    "\n",
    "# Question with RAG\n",
    "\n",
    "gpt_rag_res = chain.invoke(q)\n",
    "\n",
    "\n",
    "# Responses\n",
    "\n",
    "s = f\"\"\"\n",
    "ChatGPT Response:\n",
    "\n",
    "{gpt_res}\n",
    "\n",
    "ChatGPT with RAG Response:\n",
    "\n",
    "{gpt_rag_res}\n",
    "\"\"\"\n",
    "\n",
    "print(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "48be52de-3ce0-421b-b965-2f8989ddddff",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python",
   "language": "python",
   "name": "py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
